Flutter 内嵌原生视图 Android 端接入实现
这部分代码摘录自《Hosting native Android views in your Flutter app with Platform Views | Flutter》
模式选择
在《Flutter 内嵌原生视图能力》中提到,Flutter 在 Android 下嵌入原生视图,有 3 种模式可供选择。具体模式的选择方式,在 Dart 侧实现代码中进行指定。
根据《掘金x得物公开课 - Flutter 3.0下的混合开发演进》,在 Flutter 3.0 以后,主要通过以下两个接口:
PlatformViewsService.initSurfaceAndroidView
:走 Texture Layer Hybrid Composition 模式PlatformViewsService.initExpensiveAndroidView
:走 Hybrid composition 模式
在 Flutter 3.0 以前的 API:
PlatformViewsService.initSurfaceAndroidView
:走 Hybrid composition 模式AndroidView
实例:走 Virtual displays 模式
注意:3.0 之前和之后,
initSurfaceAndroidView
所对应的模式是不一样的。
现在看到上面这几个 API 有点懵,在读完下一节 Dart 侧实现,就容易理解了。
Dart 侧代码实现
Dart 侧需要创建一个 Widget,并添加相关实现。具体根据不同的模式,实现方法不同。
Hybrid composition
Widget 的 build 方法:
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
//……
Widget build(BuildContext context) {
// This is used in the platform side to register the view.
const String viewType = '<platform-view-type>';
// Pass parameters to the platform side.
const Map<String, dynamic> creationParams = <String, dynamic>{};
return PlatformViewLink(
viewType: viewType,
surfaceFactory: (context, controller) {
return AndroidViewSurface(
controller: controller as AndroidViewController,
gestureRecognizers: const <Factory<OneSequenceGestureRecognizer>>{},
hitTestBehavior: PlatformViewHitTestBehavior.opaque,
);
},
onCreatePlatformView: (params) {
return PlatformViewsService.initSurfaceAndroidView(
id: params.id,
viewType: viewType,
layoutDirection: TextDirection.ltr,
creationParams: creationParams,
creationParamsCodec: const StandardMessageCodec(),
onFocus: () {
params.onFocusChanged(true);
},
)
..addOnPlatformViewCreatedListener(params.onPlatformViewCreated)
..create();
},
);
}
其中:
Virtual display
同样是创建一个 Widget。Dart import:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
Widget 的 build 方法:
Widget build(BuildContext context) {
// This is used in the platform side to register the view.
const String viewType = '<platform-view-type>';
// Pass parameters to the platform side.
final Map<String, dynamic> creationParams = <String, dynamic>{};
return AndroidView(
viewType: viewType,
layoutDirection: TextDirection.ltr,
creationParams: creationParams,
creationParamsCodec: const StandardMessageCodec(),
);
}
其中:
Android 平台侧
这里以 Java 代码为例。创建与继承自 PlatformView 的 Android 视图:
package dev.flutter.example;
import android.content.Context;
import android.graphics.Color;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import io.flutter.plugin.platform.PlatformView;
import java.util.Map;
class NativeView implements PlatformView {
@NonNull private final TextView textView;
NativeView(@NonNull Context context, int id, @Nullable Map<String, Object> creationParams) {
textView = new TextView(context);
textView.setTextSize(72);
textView.setBackgroundColor(Color.rgb(255, 255, 255));
textView.setText("Rendered on a native Android view (id: " + id + ")");
}
@NonNull
@Override
public View getView() {
return textView;
}
@Override
public void dispose() {}
}
好要创建一个继承自 PlatformViewFactory 的工厂类:
package dev.flutter.example;
import android.content.Context;
import androidx.annotation.Nullable;
import androidx.annotation.NonNull;
import io.flutter.plugin.common.StandardMessageCodec;
import io.flutter.plugin.platform.PlatformView;
import io.flutter.plugin.platform.PlatformViewFactory;
import java.util.Map;
class NativeViewFactory extends PlatformViewFactory {
NativeViewFactory() {
super(StandardMessageCodec.INSTANCE);
}
@NonNull
@Override
public PlatformView create(@NonNull Context context, int id, @Nullable Object args) {
final Map<String, Object> creationParams = (Map<String, Object>) args;
return new NativeView(context, id, creationParams);
}
}
然后,将工厂类注册到引擎中去:
package dev.flutter.example;
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
public class MainActivity extends FlutterActivity {
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
flutterEngine
.getPlatformViewsController()
.getRegistry()
.registerViewFactory("<platform-view-type>", new NativeViewFactory());
}
}
如果是进行插件开发,注册方法如下:
package dev.flutter.plugin.example;
import androidx.annotation.NonNull;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
public class PlatformViewPlugin implements FlutterPlugin {
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
binding
.getPlatformViewRegistry()
.registerViewFactory("<platform-view-type>", new NativeViewFactory());
}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {}
}
build.gradle 需要修改:
android {
defaultConfig {
minSdkVersion 19 // if using hybrid composition
minSdkVersion 20 // if using virtual display.
}
}
相关类:
本文作者:Maeiee
本文链接:Flutter 内嵌原生视图 Android 端接入实现
版权声明:如无特别声明,本文即为原创文章,版权归 Maeiee 所有,未经允许不得转载!
喜欢我文章的朋友请随缘打赏,鼓励我创作更多更好的作品!